/**
 * @Author wangyl
 * @E-mail wangyl0629@foxmail.com
 **/
package com.wyl.xue.admin.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wyl.xue.admin.system.mybatis.entity.SystemRoleMenu;
import com.wyl.xue.admin.system.mybatis.entity.SystemRoles;
import com.wyl.xue.admin.system.mybatis.service.SystemRoleMenuService;
import com.wyl.xue.admin.system.mybatis.service.SystemRolesService;
import com.wyl.xue.admin.system.mybatis.service.SystemUserRoleService;
import com.wyl.xue.admin.system.service.Role;
import com.wyl.xue.admin.system.vo.RoleInfoVo;
import com.wyl.xue.core.util.UserTools;
import com.wyl.xue.core.util.exception.BizException;
import com.wyl.xue.core.util.result.ResultCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName: RoleImpl
 * @Function: TODO
 * @Date: 2020/11/8 15:42
 * @author wyl
 * @version V1.0
 */
@AllArgsConstructor
@Service
@Slf4j
public class RoleImpl implements Role {
    /**
     * 复制对象 从DepartmentInfoVo 复制为SystemDepartment
     */
    final BeanCopier copierTo = BeanCopier.create(RoleInfoVo.class, SystemRoles.class, false);
    final BeanCopier copierFrom = BeanCopier.create(SystemRoles.class, RoleInfoVo.class, false);
    final SystemRolesService systemRolesService;
    final SystemUserRoleService systemUserRoleService;
    final SystemRoleMenuService systemRoleMenuService;

    /**
     * @Description 添加角色信息
     * @param roleInfoVo
     * @return void
     * @Date 2020/11/8 18:43
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public void addRole(RoleInfoVo roleInfoVo) {
        SystemRoles systemRoles = new SystemRoles();
        copierTo.copy(roleInfoVo, systemRoles, null);
        systemRoles.setOperator(UserTools.tools.getUserNameByRequest());
        systemRolesService.save(systemRoles);
        setRoleMenus(roleInfoVo.getMenuIds(), systemRoles.getRoleId(), false);
    }

    /**
     * @Description 删除角色信息
     * @param id
     * @return void
     * @Date 2020/11/8 18:43
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(long id) {
        if (systemUserRoleService.getSystemUserRoleByRoleId(id)
                                 .isEmpty()) {
            systemRolesService.removeById(id);
            systemRoleMenuService.deleteRoleMenusByroleId(id);
            return;
        }
        throw new BizException(ResultCode.HAVERESOURCES);
    }

    /**
     * @Description 获取所有角色信息
     * @return java.util.List<com.wyl.xue.admin.system.vo.RoleInfoVo>
     * @Date 2020/11/8 18:44
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public List<RoleInfoVo> getRoleAll() {
        LambdaQueryWrapper<SystemRoles> systemRolesLambdaQueryWrapper = Wrappers.lambdaQuery(SystemRoles.class);
        List<SystemRoles> systemRoles = systemRolesService.list(systemRolesLambdaQueryWrapper);
        List<RoleInfoVo> roleInfoVos = systemRoles.parallelStream()
                                                  .map(systemRole -> {
                                                      RoleInfoVo roleInfoVo = new RoleInfoVo();
                                                      copierFrom.copy(systemRole, roleInfoVo, null);
                                                      return roleInfoVo;
                                                  })
                                                  .collect(Collectors.toList());
        return roleInfoVos;
    }

    /**
     * @Description 分页获取角色信息
     * @param page
     * @param size
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.wyl.xue.admin.system.mybatis.entity.SystemRoles>
     * @Date 2020/11/8 18:44
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public IPage<SystemRoles> getRoleForPage(int page, int size) {
        Page<SystemRoles> systemRolesPage = new Page<>(page, size);
        return systemRolesService.page(systemRolesPage);
    }

    /**
     * @Description 更新角色信息
     * @param roleInfoVo
     * @return void
     * @Date 2020/11/8 18:44
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(RoleInfoVo roleInfoVo) {
        SystemRoles systemRoles = new SystemRoles();
        copierTo.copy(roleInfoVo, systemRoles, null);
        systemRoles.setOperator(UserTools.tools.getUserNameByRequest());
        systemRolesService.updateById(systemRoles);
        setRoleMenus(roleInfoVo.getMenuIds(), systemRoles.getRoleId(), true);
    }

    /**
     * @Description
     * @param roleId
     * @return java.util.List<java.lang.Long>
     * @Date 2020/11/11 14:43
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public List<Long> getRoleMenusByRoleId(long roleId) {
        List<SystemRoleMenu> menusByRole = systemRoleMenuService.getMenusByRole(roleId);
        List<Long> MenuIds = menusByRole.parallelStream()
                                        .map(SystemRoleMenu::getMenuId)
                                        .collect(Collectors.toList());
        return MenuIds;
    }

    /**
     * @Description 通过用户id 获取角色id
     * @param userId
     * @return java.util.List<java.lang.Long>
     * @Date 2020/11/16 23:17
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public List<Long> getRoleIdsByUserId(long userId) {
        return systemUserRoleService.getSystemUserRoleByUserId(userId);
    }

    /**
     * @Description 搜索角色信息
     * @param roleInfoVo
     * @return java.util.List<com.wyl.xue.admin.system.mybatis.entity.SystemRoles>
     * @Date 2020/11/20 16:17
     * @Author wangyl
     * @Version V1.0
     */
    @Override
    public List<SystemRoles> searchRole(RoleInfoVo roleInfoVo) {
        LambdaQueryWrapper<SystemRoles> menuLambdaQueryWrapper = Wrappers.lambdaQuery(SystemRoles.class)
                                                                         .like(!Objects.isNull(roleInfoVo.getRoleName()), SystemRoles::getRoleName, roleInfoVo.getRoleName())
                                                                         .like(!Objects.isNull(roleInfoVo.getRoleCode()), SystemRoles::getRoleCode, roleInfoVo.getRoleCode());
        return systemRolesService.list(menuLambdaQueryWrapper);
    }

    /**
     * @Description 设置角色和菜单关联信息
     * @param menuIds 菜单id列表
     * @param roleId 角色id
     * @param deleteHistory 是否清楚历史数据
     * @return void
     * @Date 2020/11/10 18:12
     * @Author wangyl
     * @Version V1.0
     */
    private void setRoleMenus(List<Long> menuIds, long roleId, Boolean deleteHistory) {
        List<SystemRoleMenu> systemRoleMenus = menuIds.parallelStream()
                                                      .map(ids -> SystemRoleMenu.builder()
                                                                                .menuId(ids)
                                                                                .roleId(roleId)
                                                                                .build())
                                                      .collect(Collectors.toList());
        if (deleteHistory) {
            systemRoleMenuService.deleteRoleMenusByroleId(roleId);
        }
        systemRoleMenuService.saveBatch(systemRoleMenus);
    }
}
